package projectx.core.dao;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import projectx.util.StringUtil;

public class Parameter {

	public static final String MSG_STREAM_IO_EXCEPTION = "MSG_STREAM_IO_EXCEPTION";

	public static final String WHERE_CONDITION = "where_condition";

	private Map _data = new HashMap();

	private Map _type = new HashMap();

	private Map _replacement = new HashMap();

	private Map _length = new HashMap();

	public void setString(String name, String value) {
		String tempData = value;

		if (tempData != null) {
			tempData = StringUtil.replaceAll(tempData, "'", "${QUOTE}");
			tempData = StringUtil.replaceAll(tempData, "${QUOTE}", "''");
			tempData = tempData.trim();
		}

		_data.put(name, tempData);

		_type.put(name, new Integer(Types.VARCHAR));
	}

	public void setWhere(String value) {

		_data.put(WHERE_CONDITION, value);

		_type.put(WHERE_CONDITION, new Integer(Types.VARCHAR));
	}

	public void setBoolean(String name, Boolean value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.BIT));
	}

	public void setByte(String name, Byte value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.TINYINT));
	}

	public void setShort(String name, Short value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.SMALLINT));
	}

	public void setInt(String name, Integer value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.INTEGER));
	}

	public void setLong(String name, Long value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.BIGINT));
	}

	public void setFloat(String name, Float value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.REAL));
	}

	public void setDouble(String name, Double value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.DOUBLE));
	}

	public void setBigDecimal(String name, BigDecimal value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.DECIMAL));
	}

	public void setDate(String name, Date value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.DATE));
	}

	public void setTime(String name, Time value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.TIME));
	}

	public void setTimestamp(String name, Timestamp value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.TIMESTAMP));
	}

	public void setBytes(String name, byte[] value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.BINARY));
	}

	public void setBinaryStream(String name, InputStream value) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.BLOB));
	}

	public void setCharacterStream(String name, Reader value, int len) {
		_data.put(name, value);
		_type.put(name, new Integer(Types.CLOB));
		this._length.put(name, new Integer(len));
	}

	public void setObject(String name, Object value, int sqlType) {
		_data.put(name, value);
		_type.put(name, new Integer(sqlType));
	}

	public void replace(String name, String str) {
		_replacement.put(name, str);
	}

	public String getReplacement(String name) {
		return (String) _replacement.get(name);
	}

	public Object getObject(String name) {

		Object value = _data.get(name);

		if (WHERE_CONDITION.equals(name)) {
			return " " + (String) value;
		}

		return value;
	}

	public int getSqlType(String name) {
		Object sqlType = _type.get(name);
		if (sqlType == null) {
			return Types.NULL;
		}
		return ((Integer) sqlType).intValue();
	}

	public int length(String name) {
		Object value = getObject(name);
		if (value == null) {
			return -1;
		}
		if (value instanceof InputStream) {
			try {
				return ((InputStream) value).available();
			} catch (IOException e) {
				IllegalStateException ise = new IllegalStateException(
						MSG_STREAM_IO_EXCEPTION);
				ise.initCause(e);
				throw ise;
			}
		}
		if (value instanceof byte[]) {
			return ((byte[]) value).length;
		}
		if (value instanceof Reader) {
			return ((Integer) _length.get(name)).intValue();
		}
		return value.toString().length();
	}

	public boolean containsKey(String name) {
		return _type.containsKey(name);
	}

	public void remove(String name) {
		_data.remove(name);
		_type.remove(name);
	}

	public String toString() {
		StringBuffer buf = new StringBuffer("{");
		Iterator it = _data.entrySet().iterator();
		boolean isSecond = false;
		while (it.hasNext()) {
			if (isSecond) {
				buf.append(", ");
			}
			Map.Entry entry = (Map.Entry) it.next();
			buf.append(entry.getKey());
			buf.append("=");
			buf.append(entry.getValue());
			isSecond = true;
		}
		buf.append("}");
		return buf.toString();
	}
}
